Skip to content

[SPIR-V] Add descriptor heap -fvk-resource-heap-stride / -fvk-sampler-heap-stride CLI flags - #8519

Open
Jonathan Zakharov (jzakharovnv) wants to merge 14 commits into
microsoft:mainfrom
jzakharovnv:pr3-cli-stride-flags
Open

[SPIR-V] Add descriptor heap -fvk-resource-heap-stride / -fvk-sampler-heap-stride CLI flags#8519
Jonathan Zakharov (jzakharovnv) wants to merge 14 commits into
microsoft:mainfrom
jzakharovnv:pr3-cli-stride-flags

Conversation

@jzakharovnv

Copy link
Copy Markdown
Collaborator

Building off of #8518, this PR adds two new command-line flags that override the ArrayStride of the descriptor heap runtime arrays emitted by -fspv-use-descriptor-heap. It is part 3/4 in a series.

-fvk-resource-heap-stride and -fvk-sampler-heap-stride sets the stride for ResourceDescriptorHeap SamplerDescriptorHeap arrays respectively. N and M must be a power of two in [8, 256]. When set, the CLI value takes the highest precedence.

Assisted by an AI agent.

Diego Novillo (@dnovillo)

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

✅ With the latest revision this PR passed the C/C++ code formatter.

@jzakharovnv
Jonathan Zakharov (jzakharovnv) force-pushed the pr3-cli-stride-flags branch 3 times, most recently from 1e2a278 to 5e7b928 Compare June 4, 2026 22:59
@jzakharovnv

Copy link
Copy Markdown
Collaborator Author

@microsoft-github-policy-service agree company="NVIDIA"

Comment thread docs/SPIR-V.rst Outdated
can be overridden, in increasing order of precedence:

- ``[[vk::resource_heap_stride_constant_id(id)]]`` and
``[[vk::sampler_heap_stride_constant_id(id)]]`` on a ``uint`` global emit the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These spec constant attributes are actually in #8520, right? Maybe move them there? This way, this PR just handles the flags.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was a bit clumsy on my part. Will fix the documentation to remove mention of (now dropped feature) stride spec const attributes.

!handleHeapStride(Args, OPT_fvk_sampler_heap_stride,
&opts.SpirvOptions.samplerHeapStride,
"-fvk-sampler-heap-stride", errors)) {
return 1;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If both flags are wrong, this will short-circuit and only give a single error message. Could you make both calls always happen and return the aggregate? Something like this:

bool ok = handleHeapStride(...resource...);
ok &= handleHeapStride(...sampler...);
if (!ok) return 1;

@github-project-automation github-project-automation Bot moved this from New to In progress in HLSL Roadmap Jul 17, 2026
@dnovillo Diego Novillo (dnovillo) added the spirv Work related to SPIR-V label Jul 17, 2026
@jzakharovnv
Jonathan Zakharov (jzakharovnv) force-pushed the pr3-cli-stride-flags branch 3 times, most recently from 6bc5a9e to c69d8a0 Compare July 23, 2026 19:35

@dnovillo Diego Novillo (dnovillo) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fixes. LGTM now.

Building off of microsoft#8281, this commit adds a native lowering via SPV_EXT_descriptor_heap and SPV_KHR_untyped_pointers.

ResourceDescriptorHeap and SamplerDescriptorHeap are lowered to untyped variables decorated with ResourceHeapEXT and SamplerHeapEXT. Each heap access emits OpUntypedAccessChainKHR into a runtime array of the appropriate descriptor type. Buffer-like resources (StructuredBuffer, ByteAddressBuffer, ConstantBuffer, TextureBuffer) use OpTypeBufferEXT and OpBufferPointerEXT; image and sampler resources use OpLoad. Interlocked operations on RWTexture use OpUntypedImageTexelPointerEXT.

Requires -fspv-target-env=vulkan1.3.

Assisted-by: Claude.
@damyanp

Copy link
Copy Markdown
Member

[Auto-generated note from Damyan Pepper (@damyanp)]

This looks like a user-visible bug fix/feature change. Please add (or point to) the corresponding entry in docs/ReleaseNotes.md.

If release-note coverage is planned in a related PR (including one that hasn’t been submitted yet), please mention that plan/link so we can avoid duplicate notes.

Extends the SPV_EXT_descriptor_heap native heap lowering to cover RaytracingAccelerationStructure resources loaded from ResourceDescriptorHeap.

Acceleration structure descriptors are accessed via OpUntypedAccessChainKHR into a runtime array of OpTypeAccelerationStructureKHR, consistent with the image and sampler paths added in the previous commit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds configurable resource and sampler descriptor-heap strides while expanding native SPV_EXT_descriptor_heap lowering.

Changes:

  • Adds and validates the two stride CLI options.
  • Supports literal and computed descriptor-array strides, including acceleration structures.
  • Expands documentation and SPIR-V regression coverage.

Reviewed changes

Copilot reviewed 57 out of 57 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tools/clang/unittests/SPIRV/SpirvContextTest.cpp Tests runtime-array uniquing.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.typed-formats.hlsl Tests typed image formats.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texturecube.hlsl Tests cube textures.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture.hlsl Tests buffer textures.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture-sampler-assignment.hlsl Tests texture/sampler reassignment.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture-ms.hlsl Tests multisampled textures.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.texture-dims.hlsl Tests sampled texture dimensions.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.structured-buffer-atomic.hlsl Tests structured-buffer atomics.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.stride-cli.hlsl Tests literal CLI strides.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.stride-cli-permute.hlsl Tests stride values and validation.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.static-global.hlsl Tests static resource aliases.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.sampler-comparison.hlsl Tests comparison samplers.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.sample-grad-bias.hlsl Tests gradient and bias sampling.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.rwtexture-dims.hlsl Tests storage texture dimensions.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.rwtexture-atomics.hlsl Tests untyped image atomics.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.rwbyteaddressbuffer.hlsl Tests writable byte buffers.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.nonuniform.hlsl Tests divergent heap indexing.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.mixed-bound.hlsl Tests bound/heap coexistence.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.mixed-alias.error.hlsl Tests mixed-alias diagnostics.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.load-offset.hlsl Tests texture-load offsets.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.groupshared.hlsl Tests groupshared interoperability.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.gather.hlsl Tests texture gathers.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.function-params.hlsl Tests resource parameters.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.discarded.error.hlsl Tests discarded-access diagnostics.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.counter-ops.error.hlsl Tests unsupported counter diagnostics.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.constant-texture-buffer.hlsl Tests constant/texture buffers.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.constant-buffer-assignment.hlsl Tests constant-buffer reassignment.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.buffer.hlsl Tests buffer heap lowering.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.array-stride.hlsl Tests computed default strides.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.array-stride.accelstruct.hlsl Tests acceleration-structure strides.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.append-consume.error.hlsl Tests append/consume diagnostics.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.acceleration-structure.stride.error.hlsl Tests acceleration-stride errors.
tools/clang/test/CodeGenSPIRV/sm6_6.descriptorheap.ext.acceleration-structure.hlsl Tests acceleration-structure loads.
tools/clang/test/CodeGenSPIRV/resource-heap-ext-texture.hlsl Removes superseded coverage.
tools/clang/lib/SPIRV/SpirvType.cpp Includes stride IDs in type equality.
tools/clang/lib/SPIRV/SpirvInstruction.cpp Implements new SPIR-V instructions.
tools/clang/lib/SPIRV/SpirvEmitter.h Declares descriptor-heap helpers/state.
tools/clang/lib/SPIRV/SpirvEmitter.cpp Implements native heap lowering and strides.
tools/clang/lib/SPIRV/SpirvContext.cpp Uniques extended descriptor types.
tools/clang/lib/SPIRV/SpirvBuilder.cpp Builds computed heap strides.
tools/clang/lib/SPIRV/LowerTypeVisitor.cpp Lowers untyped image pointers.
tools/clang/lib/SPIRV/EmitVisitor.h Declares new emission handlers.
tools/clang/lib/SPIRV/EmitVisitor.cpp Emits new types, constants, and decorations.
tools/clang/lib/SPIRV/DeclResultIdMapper.h Declares function alias support.
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp Implements function aliases.
tools/clang/lib/SPIRV/CapabilityVisitor.cpp Requires Vulkan 1.3 for native heaps.
tools/clang/lib/SPIRV/AstTypeProbe.cpp Detects acceleration structures.
tools/clang/include/clang/SPIRV/SpirvVisitor.h Extends visitor dispatch.
tools/clang/include/clang/SPIRV/SpirvType.h Stores runtime-array stride IDs.
tools/clang/include/clang/SPIRV/SpirvInstruction.h Defines new instruction classes.
tools/clang/include/clang/SPIRV/SpirvContext.h Exposes extended type uniquing.
tools/clang/include/clang/SPIRV/SpirvBuilder.h Exposes stride construction APIs.
tools/clang/include/clang/SPIRV/AstTypeProbe.h Declares acceleration-type detection.
lib/DxcSupport/HLSLOptions.cpp Parses and validates stride options.
include/dxc/Support/SPIRVOptions.h Stores stride overrides.
include/dxc/Support/HLSLOptions.td Defines the CLI flags.
docs/SPIR-V.rst Documents native heaps and strides.

Comment on lines +7207 to +7208
if (isRaytracingAccelerationStructure(resourceType) &&
!spvBuilder.resourceHeapStrideIncludesAccelStruct()) {
Comment on lines +1215 to +1221
bool strideOk = true;
strideOk &= handleHeapStride(Args, OPT_fvk_resource_heap_stride,
&opts.SpirvOptions.resourceHeapStride,
"-fvk-resource-heap-stride", errors);
strideOk &= handleHeapStride(Args, OPT_fvk_sampler_heap_stride,
&opts.SpirvOptions.samplerHeapStride,
"-fvk-sampler-heap-stride", errors);
// [[RS]] = resource-heap stride, [[SS]] = sampler-heap stride (per-RUN via -D).

// ---- Full 6x6 cross product of {8,16,32,64,128,256} x {8,16,32,64,128,256} ----
// RUN: %dxc -T cs_6_6 -E main -Od -fspv-use-descriptor-heap -fspv-target-env=vulkan1.3 -fvk-resource-heap-stride 8 -fvk-sampler-heap-stride 8 -spirv %s | FileCheck %s -DRS=8 -DSS=8
Comment on lines +374 to +376
if (!args.hasArg(OPT_spirv)) {
errors << name << " requires -spirv";
return false;
Comment on lines +457 to +460
def fvk_resource_heap_stride : Separate<["-"], "fvk-resource-heap-stride">, MetaVarName<"<stride>">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
HelpText<"Override the byte ArrayStride of the resource descriptor heap runtime array. Must be a power of 2 in [8, 256].">;
def fvk_sampler_heap_stride : Separate<["-"], "fvk-sampler-heap-stride">, MetaVarName<"<stride>">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
HelpText<"Override the byte ArrayStride of the sampler descriptor heap runtime array. Must be a power of 2 in [8, 256].">;
@dnovillo

Copy link
Copy Markdown
Collaborator

Added an analysis on this series: #8517 (comment)


bool isRaytracingAccelerationStructure(QualType type) {
if (const auto *rt = type->getAs<RecordType>()) {
return rt->getDecl()->getName() == "RaytracingAccelerationStructure";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This string matching stuff is really gross. I posted a PR to clean this all up across the SPIRV code generator:
#8755

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, thanks! Also I'm looking into addressing your comments for #8518 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

spirv Work related to SPIR-V

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

5 participants